package es.udc.emarketapp.http.controller.actions.purchases;

import es.udc.emarketapp.emarket.model.category.vo.CategoryVO;
import es.udc.emarketapp.emarket.model.categoryFacade.CategoryFacade;
import es.udc.emarketapp.emarket.model.client.vo.ClientVO;
import es.udc.emarketapp.emarket.model.order.vo.OrderVO;
import es.udc.emarketapp.emarket.model.orderLine.vo.OrderLineVO;
import es.udc.emarketapp.emarket.model.product.vo.ProductVO;
import es.udc.emarketapp.emarket.model.productFacade.ProductFacade;
import es.udc.emarketapp.emarket.model.productFacade.vo.ProductChunkVO;
import es.udc.emarketapp.emarket.model.purchase.purchaseFacade.PurchaseFacade;
import es.udc.emarketapp.emarket.model.purchase.purchaseFacade.vo.OrderChunkVO;
import es.udc.emarketapp.emarket.model.purchase.purchaseFacade.vo.PurchaseChunkVO;
import es.udc.emarketapp.emarket.model.purchase.vo.PurchaseVO;
import es.udc.emarketapp.emarket.model.seller.vo.SellerVO;
import es.udc.emarketapp.emarket.model.shoppingFacade.vo.OrderCartVO;
import es.udc.emarketapp.emarket.model.shoppingFacade.vo.OrderLineCartVO;
import es.udc.emarketapp.emarket.model.usersFacade.UsersFacade;
import es.udc.emarketapp.emarket.util.GlobalLimits;
import es.udc.emarketapp.http.controller.session.SessionManager;
import es.udc.emarketapp.http.view.actionForms.FindPurchasesForm;
import es.udc.fbellas.j2ee.util.exceptions.InstanceNotFoundException;
import es.udc.fbellas.j2ee.util.exceptions.InternalErrorException;
import es.udc.fbellas.j2ee.util.exceptions.ModelException;
import es.udc.fbellas.j2ee.util.struts.action.DefaultAction;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

public class FindPurchasesAction extends DefaultAction {

    public final static String ORDERS_ATTRIBUTE = "orders";

    public ActionForward doExecute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException, InternalErrorException {

        /* Get data. */
        String idUser = SessionManager.getIdUser(request);

        FindPurchasesForm findForm = (FindPurchasesForm) form;
        String identifierType = findForm.getIdentifierType();
        Long identifierAsLong = findForm.getIdentifierAsLong();
        String identifier = findForm.getIdentifier();


        if (FindPurchasesForm.PURCHASE_IDENTIFIER.equals(identifierType)) {

            return doFindPurchaseById(mapping, identifierAsLong,
                    findForm.getStartIndex(), findForm.getCount(), request);

        } else {

            return doFindPurchasesByClient(mapping, identifier,
                    findForm.getStartIndex(), findForm.getCount(), request);
        }

    }

    private ActionForward doFindPurchaseById(ActionMapping mapping,
            Long identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {


        try {

            PurchaseFacade purchaseFacade = new PurchaseFacade();

            PurchaseVO purchaseVO = purchaseFacade.findPurchaseById(identifier);

            OrderChunkVO orderChunkVO = purchaseFacade.findOrdersByPurchase(
                    identifier, 1, GlobalLimits.MAX_ORDERS_FOR_PURCHASE);
            /* startIndex, count); */

            System.out.println(orderChunkVO.getExistMoreOrders());

            if (orderChunkVO.getOrderVOs().size() > 0) {

                request.setAttribute("purchase", purchaseVO);
                request.setAttribute("orders", orderChunkVO.getOrderVOs());



                List<OrderVO> orders = orderChunkVO.getOrderVOs();
                List<OrderCartVO> ordersCart = new ArrayList<OrderCartVO>();

                UsersFacade usersFacade = new UsersFacade();
                ProductFacade productFacade = new ProductFacade();
                SellerVO seller;
                ProductVO product;
                String nomEmp;
                String nomProd;
                Double precioProd;

                for (OrderVO order : orders) {

                    //recuperamos el nombre de la empresa
                    seller = usersFacade.findSellerById(
                            order.getOrderDetails().getIdVendedor());
                    nomEmp = seller.getNomEmp();

                    //creamos los LineOrderCarts a partir de los LineOrders
                    List<OrderLineCartVO> orderLinesCart =
                            new ArrayList<OrderLineCartVO>();

                    for (OrderLineVO orderLine : order.getOrderLines()) {

                        //recuperamos el nombre de producto y precio
                        product = productFacade.findProductById(
                                orderLine.getIdProd());
                        nomProd = product.getNomProd();
                        precioProd = product.getPrecio();


                        orderLinesCart.add(new OrderLineCartVO(
                                orderLine.getnLinea(), orderLine.getnPedido(),
                                orderLine.getnCompra(), orderLine.getIdProd(),
                                nomProd, orderLine.getUds(), precioProd,
                                orderLine.getValor(), orderLine.getPeso()));
                    }


                    ordersCart.add(new OrderCartVO(nomEmp,
                            order.getOrderDetails(), orderLinesCart));

                }

                request.setAttribute(ORDERS_ATTRIBUTE, ordersCart);

            }

            return mapping.findForward("FindPurchaseByIdSuccess");

        } catch (InstanceNotFoundException e) {

            ActionMessages errors = new ActionMessages();

            errors.add("identifier",
                    new ActionMessage("ErrorMessages.purchase.notFound"));
            saveErrors(request, errors);

            return new ActionForward(mapping.getInput());
        }
    }

    private ActionForward doFindPurchasesByClient(ActionMapping mapping,
            String identifier, int startIndex, int count,
            HttpServletRequest request) throws InternalErrorException {


        PurchaseFacade purchaseFacade = new PurchaseFacade();
        PurchaseChunkVO purchaseChunkVO = purchaseFacade.findPurchasesByClient(identifier, startIndex, count);


        if (purchaseChunkVO.getPurchaseVOs().size() > 0) {
            request.setAttribute("purchases", purchaseChunkVO.getPurchaseVOs());
        }

        /* Generate parameters for previous and next links. */
        Map previousLinkParameters = getPreviousLinkParameters(identifier,
                startIndex, count);

        if (previousLinkParameters != null) {
            request.setAttribute("previous", previousLinkParameters);
        }

        if (purchaseChunkVO.getExistMorePurchases()) {
            Map nextLinkParameters = getNextLinkParameters(identifier,
                    startIndex, count);
            request.setAttribute("next", nextLinkParameters);

        }

        /* Return ActionForward. */
        return mapping.findForward("FindPurchasesByClientSuccess");

    }

    private Map getPreviousLinkParameters(String identifier, int startIndex,
            int count) {

        Map linkAttributes = null;

        if ((startIndex - count) > 0) {

            linkAttributes = getCommonPreviousNextLinkParameters(identifier,
                    startIndex, count);
            linkAttributes.put("startIndex", new Integer(startIndex - count));

        }

        return linkAttributes;

    }

    private Map getNextLinkParameters(String identifier, int startIndex, int count) {

        Map linkAttributes = getCommonPreviousNextLinkParameters(identifier,
                startIndex, count);
        linkAttributes.put("startIndex", new Integer(startIndex + count));

        return linkAttributes;

    }

    private Map getCommonPreviousNextLinkParameters(String identifier,
            int startIndex, int count) {

        Map linkAttributes = new HashMap();

        linkAttributes.put("identifierType", FindPurchasesForm.CLIENT_IDENTIFIER);
        linkAttributes.put("identifier", identifier);
        linkAttributes.put("count", new Integer(count));

        return linkAttributes;

    }
}
